﻿using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Core.SqlBuilder;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Bill.PlugIn;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.Bill.PlugIn.Args;
using Kingdee.BOS.Core.List.PlugIn.Args;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using System.ComponentModel;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.Metadata.EntityElement;
using SPCom.Junit.BusinessPlugIn.SaleOrderAdjust.BillEditPlugIn.Service.Req;
using Kingdee.BOS.Util;

namespace SPCom.Junit.BusinessPlugIn.SaleOrderAdjust.BillEditPlugIn
{

    /// <summary>
    /// 销售订单调整单--单据插件
    /// </summary>
    [Kingdee.BOS.Util.HotUpdate]
    [Description("SaleOrderAdjustBill")]
    public class SalrOrderBillEdit : AbstractBillPlugIn
    {

        /// <summary>
        /// 单据页面初始化事件
        /// </summary>
        /// <remarks>
        /// 单据初始化页面时调用。
        /// </remarks>
        /// <param name="e">初始化事件参数</param>
        public override void OnBillInitialize(BillInitializeEventArgs e)
        {
            PrintEventInfo("OnBillInitialize", e);
            base.OnBillInitialize(e);
        }
        /// <summary>
        /// 选单过程，展示可选源单据；捕获此事件，调整可选的单据类型
        /// </summary>
        /// <param name="e"></param>
        public override void OnShowConvertOpForm(ShowConvertOpFormEventArgs e)
        {
            base.OnShowConvertOpForm(e);
        }
        /// <summary>
        /// 选单/下推过程, 确定单据转换规则
        /// </summary>
        /// <param name="e"></param>
        public override void OnGetConvertRule(GetConvertRuleEventArgs e)
        {
            base.OnGetConvertRule(e);
        }
        /// <summary>
        /// 上/下查过程，获得上/下查结果；捕获此事件，调整上/下查结果
        /// </summary>
        /// <param name="e"></param>
        public override void OnShowTrackResult(ShowTrackResultEventArgs e)
        {
            base.OnShowTrackResult(e);
        }
        /// <summary>
        /// 模型层数据包创建创建前事件
        /// </summary>
        /// <param name="e"></param>
        public override void BeforeCreateModelData(EventArgs e)
        {
            base.BeforeCreateModelData(e);
        }
        /// <summary>
        /// 在根据编码检索数据之前调用；
        /// 通过重载本事件，可以设置必要的过滤条件，以限定检索范围；
        /// 还可以控制当前过滤是否启用组织隔离，数据状态隔离
        /// </summary>
        /// <param name="e"></param>
        public override void BeforeSetItemValueByNumber(BeforeSetItemValueByNumberArgs e)
        {
            PrintEventInfo("BeforeSetItemValueByNumber", e);
            base.BeforeSetItemValueByNumber(e);
            switch (e.BaseDataField.Key.ToUpperInvariant())
            {
                //case "FXXX":通过字段的Key[大写]来区分不同的基础资料
                //e.Filter = "FXXX= AND fxxy=";过滤的字段使用对应基础资料的字段的Key，支持ksql语法
                //break;
                case "":
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 显示基础资料列表之前调用
        /// 通过重载本事件，可以设置必要的过滤条件，以限定检索范围；
        /// </summary>
        /// <param name="e"></param>
        public override void BeforeF7Select(BeforeF7SelectEventArgs e)
        {
            base.BeforeF7Select(e);
            PrintEventInfo("BeforeF7Select", e);
            switch (e.FieldKey.ToUpperInvariant())
            {
                //case "FXXX":通过字段的Key[大写]来区分不同的基础资料
                //    e.ListFilterParameter.Filter = "FXXX= AND fxxy=";过滤的字段使用对应基础资料的字段的Key，支持ksql语法
                //break;
                case "":
                    break;
                default:
                    break;
            }
        }
        /// <summary>
        /// 界面数据发生变化之后，需要处理的功能
        /// </summary>
        /// <param name="e"></param>
        public override void DataChanged(DataChangedEventArgs e)
        {
            //this.View.ShowMessage("值更新了，查看备注");
            //this.Model.SetValue("FNote","更新值：" + e.Field + ",");
            // string msg = this.Model.GetValue("FNote").ToString() + e.Field + ",";
            this.Model.SetValue("FNote", "更新值测试，更新时间：" + DateTime.Now.ToString("G"));

            base.DataChanged(e);
            PrintEventInfo("DataChanged", e);
            switch (e.Field.Key.ToUpperInvariant())
            {
                case "":
                    break;
                default:
                    break;
            }
        }
        /// <summary>
        /// 单据持有事件发生前需要完成的功能
        /// </summary>
        /// <param name="e"></param>
        public override void BeforeDoOperation(BeforeDoOperationEventArgs e)
        {
            base.BeforeDoOperation(e);
            PrintEventInfo("BeforeDoOperation", e);
            switch (e.Operation.FormOperation.Operation.ToUpperInvariant())
            {
                //case "SAVE": 表单定义的事件都可以在这里执行，需要通过事件的代码[大写]区分不同事件
                //break;
                case "":
                    break;
                default:
                    break;
            }
        }
        /// <summary>
        /// 单据持有事件发生后需要完成的功能
        /// </summary>
        /// <param name="e"></param>
        public override void AfterDoOperation(AfterDoOperationEventArgs e)
        {
            PrintEventInfo("AfterDoOperation", e);
            base.AfterDoOperation(e);
            switch (e.Operation.Operation.ToUpperInvariant())
            {
                //case "SAVE": 表单定义的事件都可以在这里执行，需要通过事件的代码[大写]区分不同事件
                //break;
                case "":
                    break;
                default:
                    break;
            }
        }
        /// <summary>
        /// 界面数据发生变化之前，需要处理的功能
        /// </summary>
        /// <param name="e"></param>
        public override void BeforeUpdateValue(BeforeUpdateValueEventArgs e)
        {
            PrintEventInfo("BeforeUpdateValue", e);
            base.BeforeUpdateValue(e);
            switch (e.Key.ToUpperInvariant())
            {
                //case "FXXX":通过字段的Key[大写]来区分不同的控件的数据变化功能，如果要阻止该次变化，可以用e.Cancel = true;
                //    e.Cancel = true;
                //    break;
                case "":
                    break;
                default:
                    break;
            }
        }
        /// <summary>
        /// 单据数据加载事件
        /// </summary>
        /// 单据数据加载时调用，参数是打开的单据的主键PrimaryKeyValue 和 单据数据包BizDataObject
        /// 可以在插件的LoadData方法加载数据，若插件未重载LoadData方法，系统将自动加载。
        /// <param name="e"></param>
        /// <example>
        /// 插件中可以自己为单据加载数据，加载方法如下：
        /// <code>
        /// DynamicObjectType dt = this.Model.BusinessInfo.GetDynamicObjectType();
        /// OperateOption option = OperateOption.Create();
        /// DynamicObject obj = BusinessDataServiceHelper.LoadSingle(this.Context, e.PrimaryKeyValue, dt, option);
        /// obj["Status"] = "0";
        /// e.BizDataObject = obj;
        /// </code>
        /// </example>
        public override void LoadData(LoadDataEventArgs e)
        {
            base.LoadData(e);
        }
        /// <summary>
        /// 单据数据加载完毕事件
        /// </summary>
        /// <param name="e"></param>
        public override void AfterLoadData(EventArgs e)
        {
            base.AfterLoadData(e);
        }
        /// <summary>
        /// 保存前事件（校验完毕）
        /// </summary>
        /// <param name="e"></param>
        public override void BeforeSave(BeforeSaveEventArgs e)
        {
            base.BeforeSave(e);
        }
        /// <summary>
        /// 保存失败事件
        /// </summary>
        /// <param name="e"></param>
        public override void SaveBillFailed(SaveBillFailedEventArgs e)
        {
            base.SaveBillFailed(e);
        }
        /// <summary>
        /// 保存成功后事件
        /// </summary>
        /// <param name="e"></param>
        public override void AfterSave(AfterSaveEventArgs e)
        {
            base.AfterSave(e);
        }
        /// <summary>
        /// 保存失败后事件。
        /// </summary>
        /// <param name="e"></param>
        public override void AfterSaveFailed(AfterSaveFailedEventArgs e)
        {
            base.AfterSaveFailed(e);
        }
        /// <summary>
        /// 提交前事件（校验完毕）
        /// </summary>
        /// <param name="e"></param>
        public override void BeforeSubmit(BeforeSubmitEventArgs e)
        {
            base.BeforeSubmit(e);
        }
        /// <summary>
        /// 提交成功后事件
        /// </summary>
        /// <param name="e"></param>
        public override void AfterSubmit(AfterSubmitEventArgs e)
        {
            base.AfterSubmit(e);
        }
        /// <summary>
        /// 复制单据事件
        /// </summary>
        /// <param name="e"></param>
        public override void CopyData(CopyDataEventArgs e)
        {
            base.CopyData(e);
        }
        /// <summary>
        /// 单据复制完毕事件
        /// </summary>
        /// <param name="e"></param>
        public override void AfterCopyData(CopyDataEventArgs e)
        {
            base.AfterCopyData(e);
        }
        /// <summary>
        /// 设置状态前事件
        /// </summary>
        /// <param name="e"></param>
        public override void BeforeSetStatus(BeforeSetStatusEventArgs e)
        {
            base.BeforeSetStatus(e);
        }
        /// <summary>
        /// 设置状态后事件
        /// </summary>
        /// <param name="e"></param>
        public override void AfterSetStatus(AfterSetStatusEventArgs e)
        {
            base.AfterSetStatus(e);
        }
        /// <summary>
        /// 引入数据前校验
        /// </summary>
        /// <param name="e"></param>
        public override void VerifyImportData(VerifyImportDataArgs e)
        {
            base.VerifyImportData(e);
        }
        /// <summary>
        /// 在获得基础资料使用组织之前触发；
        /// 适用于excel导入。
        /// </summary>
        /// <param name="e"></param>
        public override void BeforeImportGetBaseDataUseOrg(BeforeGetBaseDataUseOrgArgs e)
        {
            base.BeforeImportGetBaseDataUseOrg(e);
        }
        /// <summary>
        ///  下推过程中，目标单改变事件
        /// </summary>
        /// <param name="e"></param>
        public override void OnTargetBillChanged(TargetBillChangedEventArgs e)
        {
            base.OnTargetBillChanged(e);
        }
        #region private method
        /// <summary>
        /// 事件执行次数计数器
        /// </summary>
        private int counter;
        /// <summary>
        /// 事件执行次数计数器
        /// </summary>
        private int Counter
        {
            get { return ++counter; }
        }
        /// <summary>
        /// 输出事件执行日志
        /// </summary>
        /// <param name="eventName">事件名称</param>
        /// <param name="args">事件参数</param>
        private void PrintEventInfo(string eventName, params object[] args)
        {
            var formId = GetFormId();
            var parameters = string.Empty;
            try
            {
                //parameters = Newtonsoft.Json.JsonConvert.SerializeObject(args);// 性能较差，可能会导致页面假死
            }
            catch
            {
            }
            var log = string.Format("序号:{0},执行时间:{1},表单Id:{2},事件名称:{3},事件参数:{4}", Counter, DateTime.Now.ToString("yyyy -MM-dd HH:mm:ss.fff"), formId, eventName, parameters);
            System.Diagnostics.Debug.Print(log);
            Kingdee.BOS.Log.Logger.Error("EVENT", log, null);
        }
        /// <summary>
        /// 获取业务对象标识
        /// </summary>
        /// <returns></returns>
        private string GetFormId()
        {
            var formId = string.Empty;
            if (this.View != null && this.View.BillBusinessInfo != null)
            {
                formId = this.View.BillBusinessInfo.GetForm().Id;
            }
            return formId;
        }

        /// <summary>
        /// queryservice取数方案，通过业务对象来获取数据，推荐使用
        /// </summary>
        /// <returns></returns>
        private DynamicObjectCollection GetQueryDatas()
        {
            QueryBuilderParemeter paramCatalog = new QueryBuilderParemeter()
            {
                FormId = "",//取数的业务对象
                FilterClauseWihtKey = "",//过滤条件，通过业务对象的字段Key拼装过滤条件
                SelectItems = SelectorItemInfo.CreateItems("", "", ""),//要筛选的字段【业务对象的字段Key】，可以多个，如果要取主键，使用主键名
            };

            DynamicObjectCollection dyDatas = Kingdee.BOS.ServiceHelper.QueryServiceHelper.GetDynamicObjectCollection(this.Context, paramCatalog);
            return dyDatas;
        }
        #endregion


        /// <summary>
        /// 点击按钮:后执行
        /// </summary>
        /// <param name="e"></param>
        public override void AfterBarItemClick(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.AfterBarItemClickEventArgs e)
        {
            base.AfterBarItemClick(e);

            if (e.BarItemKey.Equals("btn_Save"))
            {
                // 2.获取单据体数据集
                Entity entryEntity = this.View.BillBusinessInfo.GetEntity("FEntity");
                DynamicObjectCollection dynCollection = entryEntity.DynamicProperty.GetValue(this.Model.DataObject) as DynamicObjectCollection;

                // 2.封装数据
                // List<SaleOrderBillEdit> fillBilList = new List<SaleOrderBillEdit>();
                int rows = 0;
                for (int i = 0; i < dynCollection.Count; i++)
                {
                    if (dynCollection[i]["F_OrderBillNo"] == null || dynCollection[i]["F_OrderBillNo"].ToString().Length == 0) continue;

                    SaleOrderBillEdit vo = new SaleOrderBillEdit();
                    vo.FEntryId = Convert.ToInt32(dynCollection[i]["F_EntryId"]);
                    vo.SaleOrderNo = dynCollection[i]["F_OrderBillNo"].ToString();
                    // 数量
                    vo.ComputePriceQty = Convert.ToDecimal(dynCollection[i]["F_ComputePriceQty"].ToString());
                    // 单价
                    vo.Price = Convert.ToDecimal(dynCollection[i]["F_TaxPrice"].ToString());
                    // 单价
                    vo.AdjustPrice = Convert.ToDecimal(dynCollection[i]["F_AdjustPrice"].ToString());

                    // 3.更新数据，并返回执行成功行  
                    if (!vo.Price.Equals(vo.AdjustPrice))
                    {
                        // 调拨金额
                        vo.AdjustAmount = vo.AdjustPrice * vo.ComputePriceQty;

                        // 测试
                        string sql = "/*dialect*/UPDATE T_SAL_ORDERENTRY SET F_RTXF_PRICEDN = 100, F_RTXF_AMOUNT = 200 WHERE FBILLNO = '100012'; ";

                        StringBuilder sqlBuilder = new StringBuilder("/*dialect*/")
                            .Append("UPDATE ")
                            .Append("T_SAL_ORDERENTRY ")
                            .Append("SET F_RTXF_PRICEDN =").Append(vo.AdjustPrice).Append(",")
                            .Append("F_RTXF_AMOUNT = ").Append(vo.AdjustAmount)
                            .Append("WHERE ")
                            .Append("FBILLNO = ").Append(vo.FEntryId);
                
                        // DBUtils.Execute(this.Context, "/*dialect*/UPDATE NBDO_t_Cust100007 SET F_NBDO_CUSTOMERNAME = '测试123' WHERE FBILLNO = '100012'");
                        rows += 1;
                    }
                }

                if (rows > 0)   this.View.ShowMessage("修改成功！修改了【" + rows + "】条数据");              
                else  this.View.ShowMessage("当前未修改单价！");             
            }
        }
    }
}